<template>
  <div class="contentSearch">
    <a-form ref="formRef" :model="formState" :rules="contentHeaderParam.rules" :layout="contentHeaderParam.layout || 'inline'">
      <a-row :gutter="24" :style="{ width: '100%' }">
        <a-col :span="contentHeaderParam.colSpan || 6" v-for="(item, index) in isFold ? foldData.data : contentHeaderParam.formOptions" :key="index">
          <!-- 普通输入框 -->
          <a-form-item :label="item.label" :name="item.name" labelAlign="left" data-type="input" v-if="item.type === 'input'" :label-col="{ style: 'width: ' + item.labelWidth + 'px' || '60px' }">
            <a-input v-model:value="formState[item.name]" :placeholder="item.placeholder || ''" :addon-after="item.afterText || false" :disabled="item.disabled || false" @change="item.changeHandle" allow-clear />
          </a-form-item>
          <!-- 数字输入框 -->
          <a-form-item :label="item.label" :name="item.name" labelAlign="left" data-type="inputNumber" v-if="item.type === 'inputNumber'" :label-col="{ style: 'width: ' + item.labelWidth + 'px' || '60px' }">
            <a-input-number v-model:value="formState[item.name]" :min="item.min" :max="item?.max" :placeholder="item.placeholder || ''" :disabled="item.disabled || false" @change="item.changeHandle" allow-clear />
            <span class="afterText" v-if="item.afterText">{{ item.afterText }}</span>
          </a-form-item>
          <!-- 按钮型单选 -->
          <a-form-item :label="item.label" :name="item.name" labelAlign="left" data-type="radio" v-if="item.type === 'radio'" :label-col="{ style: 'width: ' + item.labelWidth + 'px' || '60px' }">
            <a-radio-group v-model:value="formState[item.name]" :size="item.size" :disabled="item.disabled || false" :button-style="item.buttonStyle || 'solid'" @change="item.changeHandle" :style="{ width: '100%' }">
              <a-radio-button v-for="(opt, inx) in item.childrenMap" :key="inx" :value="opt.value" :style="{ minWidth: 100 / item.childrenMap.length + '%', textAlign: 'center' }">{{ opt.name }}</a-radio-button>
            </a-radio-group>
          </a-form-item>
          <!-- 数字区间 -->
          <a-form-item :label="item.label" :name="item.name" labelAlign="left" data-type="section" v-if="item.type === 'section'" :label-col="{ style: 'width: ' + item.labelWidth + 'px' || '60px' }">
            <a-form-item-rest>
              <a-input-number v-model:value="formState[item.name].min" :min="item.min" :max="item.max" :disabled="item.minParam.disabled || false" @change="item.minParam.changeHandle" :placeholder="item.minParam.placeholder || ''" allow-clear />
            </a-form-item-rest>
            <a-input data-type="section-key" placeholder="-" disabled />
            <a-form-item-rest>
              <a-input-number v-model:value="formState[item.name].max" :min="item.min" :max="item.max" :disabled="item.maxParam.disabled || false" @change="item.maxParam.changeHandle" :placeholder="item.maxParam.placeholder || ''" allow-clear />
            </a-form-item-rest>
          </a-form-item>
          <!-- 省市区三级联动 -->
          <a-form-item :label="item.label" :name="item.name" labelAlign="left" data-type="cascader" v-if="item.type === 'cascader'" :label-col="{ style: 'width: ' + item.labelWidth + 'px' || '60px' }">
            <a-cascader v-model:value="formState[item.name]" :getPopupContainer="item.getPopupContainer || defaultPopupContainer" :fieldNames="item.fieldNames ? item.fieldNames : { label: 'label', value: 'value', children: 'children' }" :options="item.childrenMap ? item.childrenMap : region" :show-search="{ filter: item.regionFilter }" @change="item.changeHandle" :placeholder="item.placeholder || ''" allow-clear />
          </a-form-item>
          <!-- 下拉(单选/多选) -->
          <a-form-item :label="item.label" :name="item.name" labelAlign="left" data-type="select" v-if="item.type === 'select'" :label-col="{ style: 'width: ' + item.labelWidth + 'px' || '60px' }">
            <a-select v-model:value="formState[item.name]" :listHeight="item.listHeight || 256" :getPopupContainer="item.getPopupContainer || defaultPopupContainer" :optionFilterProp="item.optionFilterProp || item.fieldNames ? item.fieldNames?.value : 'value'" :options="item.childrenMap" :mode="item.multiple" :maxTagCount="item.maxTagCount || 2" :placeholder="item.placeholder" :disabled="item.disabled || false" :fieldNames="item.fieldNames || { label: 'name', value: 'value' }" @change="item.changeHandle" :filter-option="item.filterOption" show-search :allow-clear="item.isAllowClear ?? true"></a-select>
          </a-form-item>
          <!-- 树状下拉菜单) -->
          <a-form-item :label="item.label" :name="item.name" labelAlign="left" data-type="treeSelect" v-if="item.type === 'treeSelect'" :label-col="{ style: 'width: ' + item.labelWidth + 'px' || '60px' }">
            <a-tree-select v-model:value="formState[item.name]" :multiple="item.multiple" :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" :placeholder="item.placeholder || ''" :maxTagCount="item.maxTagCount || 2" :treeData="item.treeData" :treeDefaultExpandAll="item.treeDefaultExpandAll" :treeDefaultExpandedKeys="item.treeDefaultExpandedKeys" :fieldNames="item.fieldNames" show-search allow-clear></a-tree-select>
          </a-form-item>
          <!-- 时间选择/时间区间 -->
          <a-form-item :label="item.label" :name="item.name" labelAlign="left" data-type="datePicker" v-if="item.type === 'datePicker'" :label-col="{ style: 'width: ' + item.labelWidth + 'px' || '60px' }">
            <a-date-picker v-model:value="formState[item.name]" v-if="item.pickerType === 'date'" :picker="item.picker ?? 'date'" :disabled="item.disabled || false" :show-time="item.showTime" :disabledDate="item.disabledDate" :format="item.format" @change="item.changeHandle" allow-clear />
            <a-range-picker v-model:value="formState[item.name]" v-else :disabled="item.disabled || false" :show-time="item.showTime" :disabledDate="item.disabledDate" :format="item.format" @change="item.changeHandle" allow-clear />
          </a-form-item>
        </a-col>
      </a-row>
    </a-form>
    <div class="oper">
      <a-button type="link" :style="{ color: '#666666', padding: '0' }" v-if="IsShowFold" @click="foldFrom">
        <template v-if="isFold"><down-circle-outlined />&nbsp;展开</template>
        <template v-else><up-circle-outlined />&nbsp;收起</template>
      </a-button>
      <a-button v-if="contentHeaderParam.isReset" :style="{ color: '#666666', paddingLeft: '5px', paddingRight: '5px' }" type="text" @click="handleReset">
        <template #icon><EditOutlined /></template>重置
      </a-button>
      <a-button v-if="contentHeaderParam.isSearch" type="primary" @click="handleSearch" :loading="loading">
        <template #icon> <SearchOutlined /></template>查询
      </a-button>
      <slot name="oper"></slot>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'

import { SearchOutlined, EditOutlined, DownCircleOutlined, UpCircleOutlined } from '@ant-design/icons-vue'

import type { IContentSearch } from '@/types/interface/content'

import useForm from '@/hooks/useForm'
import useGlobal from '@/hooks/useGlobal'
import { useEventListener } from '@vueuse/core'

interface IPrps {
  /**搜索loading */
  loading?: boolean
  contentHeaderParam: IContentSearch
}

interface IEmits {
  (e: 'contentHeaderHandle', type: 'search' | 'reset', formState: any): void
}

const _props = withDefaults(defineProps<IPrps>(), {
  loading: false,
  contentHeaderParam: () => ({
    colSpan: 6,
    isReset: true,
    isSearch: true,
    rules: {},
    layout: 'inline',
    formOptions: [],
  }),
})
const _emits = defineEmits<IEmits>()

const { formRef, formState } = useForm()
const { proxy } = useGlobal()
const defaultPopupContainer = () => document.body

/**是否折叠 */
const isFold = ref<boolean>()
/**是否展示展开按钮 */
const IsShowFold = ref<boolean>()
/**折叠起来的数据 */
const foldData = reactive({
  data: [] as anyObject[],
  opear: [] as anyObject[],
})
/**省市区数据 */
const region = ref([])

/**
 * @method 折叠表单为一行
 */
const foldFrom = () => {
  const colSpan = 24 / _props.contentHeaderParam.colSpan || 6
  // 折叠后只显示一行该放的formItem
  foldData.data = _props.contentHeaderParam.formOptions.slice(0, colSpan)
  isFold.value = !isFold.value
}

/**
 * @method 搜索
 */
const handleSearch = proxy?.$_l.debounce(async () => {
  await formRef.value?.validate()
  _emits('contentHeaderHandle', 'search', formState.value)
}, 300)

/**
 * @method 重置
 */
const handleReset = () => {
  _props.contentHeaderParam.formOptions.forEach((item) => {
    item.value = item.defaultValue
    formState.value[item.name] = item.value
  })
  _emits('contentHeaderHandle', 'reset', formState.value)
}

/**
 * @method 初始化搜索盒子配置
 */
const initSearchConfig = () => {
  const formData = proxy?.$_l.cloneDeep(_props.contentHeaderParam.formOptions)
  formData?.forEach((el) => {
    Object.assign(formState.value, { [el.name]: el.defaultValue || '' })
  })
  const len = formData?.length || 0
  // 总长为24,用总长 / 每一份的长,如果大于一共的数量代表需要展示展开按钮
  // 例如每一份占6,一共有12个配置项,24/6 = 4,4<12则需要展开按钮，如果一共有4个配置项正好放满一行,则不需要展示展开按钮
  IsShowFold.value = 24 / _props.contentHeaderParam.colSpan < len

  foldFrom()
}

useEventListener(document, 'keydown', (e: KeyboardEvent) => {
  e.key === 'Enter' && _props.contentHeaderParam.isEnter && handleSearch?.()
})

initSearchConfig()
</script>

<style scoped lang="less">
.contentSearch {
  padding: 8px 15px;
  display: flex;
  background: #ffffff;
  transition: all 0.3s ease-in-out 0.1s;
  .oper {
    margin-right: -10px;
    margin-left: auto;
    display: flex;
    margin-top: 10px;
    margin-bottom: 10px;
    .ant-btn {
      display: flex;
      align-items: center;
    }
  }
}
.layer-main {
  width: 100%;
  border: 1px solid #d9d9d9;
  height: 34px;
  line-height: 34px;
  display: flex;
  transition: all 0.3s ease-in-out 0.1s;
  &:hover {
    border-color: #40a9ff;
  }
  .layer-icon {
    padding: 0 11px;
    height: 100%;
    background-color: #fafafa;
    border-left: 1px solid #d9d9d9;
  }
}
.layer-input {
  height: 34px;
  width: 100%;
  padding: 0 11px;
  box-sizing: border-box;
  position: relative;

  .ant-input-suffix {
    position: absolute;
    right: 10px;
    top: 10px;
  }
}
:deep(.ant-form-item-control) {
  width: 100px;
}
</style>
